/**
 * is.ts - 常用类型与格式判断工具函数集合
 * 所有函数均支持 TypeScript 类型守卫或格式验证
 */

export const is = {
  /**
   * 判断是否为数字（排除 NaN）
   * @example is.number(123) // true
   */
  number(val: unknown): val is number {
    return typeof val === 'number' && !Number.isNaN(val)
  },

  /**
   * 判断是否为字符串
   * @example is.string('abc') // true
   */
  string(val: unknown): val is string {
    return typeof val === 'string'
  },

  /**
   * 判断是否为布尔值
   * @example is.boolean(true) // true
   */
  boolean(val: unknown): val is boolean {
    return typeof val === 'boolean'
  },

  /**
   * 判断是否为函数
   * @example is.function(() => {}) // true
   */
  function(val: unknown): val is Function {
    return typeof val === 'function'
  },

  /**
   * 判断是否为对象（非 null）
   * @example is.object({}) // true
   */
  object(val: unknown): val is object {
    return val !== null && typeof val === 'object'
  },

  /**
   * 判断是否为数组
   * @example is.array([]) // true
   */
  array(val: unknown): val is any[] {
    return Array.isArray(val)
  },

  /**
   * 判断是否为 undefined
   * @example is.undefined(undefined) // true
   */
  undefined(val: unknown): val is undefined {
    return typeof val === 'undefined'
  },

  /**
   * 判断是否为 null
   * @example is.null(null) // true
   */
  null(val: unknown): val is null {
    return val === null
  },

  /**
   * 判断是否为合法邮箱地址
   * @example is.email('a@b.com') // true
   */
  email(str: string): boolean {
    return /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/.test(str)
  },

  /**
   * 判断是否为中国大陆手机号
   * @example is.phoneNumber('13800138000') // true
   */
  phoneNumber(str: string): boolean {
    return /^1[3-9]\d{9}$/.test(str)
  },

  /**
   * 判断是否为合法车架号（VIN）
   * VIN 长度为 17 位，且不包含 I、O、Q
   * @example is.vin('1HGCM82633A004352') // true
   */
  vin(str: string): boolean {
    return /^[A-HJ-NPR-Z0-9]{17}$/i.test(str)
  },

  /**
   * 判断是否为合法 URL
   * @example is.url('https://example.com') // true
   */
  url(str: string): boolean {
    try {
      new URL(str)
      return true
    }
    catch {
      return false
    }
  },

  /**
   * 判断是否为中国大陆身份证号（15位或18位）
   * @example is.idCard('11010519491231002X') // true
   */
  idCard(str: string): boolean {
    return /^\d{15}$|^\d{17}[\dX]$/i.test(str)
  },

  /**
   * 判断是否为空值：
   * null/undefined/空字符串/空数组/空对象 返回 true
   * @example is.empty({}) // true
   */
  empty(value: unknown): boolean {
    if (value == null)
      return true
    if (typeof value === 'string' || Array.isArray(value))
      return value.length === 0
    if (typeof value === 'object')
      return Object.keys(value).length === 0
    return false
  },
}
